<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Canvas 路径API</title>
	<style>
		body {
			background: #666;
			display: flex;
			flex-direction: column;
			align-items: center;
			height: 100vh;
		}

		canvas {
			background: #fff;
		}

		a {
			color: #fff;
			font-size: 24px;
		}
	</style>
</head>

<body>
	<!--


      路径有关的API

      .beginPath(); 路径开始
      .closePath(); 路径闭合

      .moveTo();    把画笔移动到某个点
      .lineTo();    从上一个点, 画线到某个点

      .arc()        找到圆心绘制圆弧
      .arcTo()      从上个点开始, 画弧线, 需要提供虚拟点和目标点以及圆弧半径，适合画矩形圆角
      .rect()       绘制一个方框

      .bezoerCirveTo() 贝塞尔曲线
      .quadraticCurveTo() 二次曲线相当于半个贝塞尔曲线

      .fill() // 填充路径
      .stroke() // 路径描边

      直线
      折线
      圆弧
      圆角矩形
      贝塞尔曲线
      二次曲线
    -->
	<ul>
		<li><a href="#绘制直线">绘制直线</a></li>
		<li><a href="#绘制曲线">绘制曲线</a></li>
		<li><a href="#绘制圆弧">绘制圆弧</a></li>
		<li><a href="#绘制圆角矩形">绘制圆角矩形</a></li>
		<li><a href="#绘制二次曲线">绘制二次曲线</a></li>
		<li><a href="#绘制矩形方框">绘制矩形方框</a></li>
	</ul>
	<div>
		<a id="绘制直线"></a>
		<h1>绘制直线</h1>
		<canvas id="canvas1" width="500" height="500"></canvas>
		<script>
			let oCanvas = document.getElementById('canvas1')
			let ctx = oCanvas.getContext('2d'); //拿到画笔
			ctx.beginPath();

			// 拿起画笔, 移动到画布的某个位置  x y 坐标
			ctx.moveTo(100, 250);

			// 绘制一条直线:  从上一个点开始到某个点 x y 坐标
			ctx.lineTo(400, 100);

			// 路径闭合: 表示路径已经绘制完毕,这里只有两点，体现不出效果
			ctx.closePath();

			// 绘制路径
			ctx.stroke();

		</script>
	</div>

	<div>
		<a id="绘制矩形方框"></a>
		<h1>绘制矩形方框</h1>
		<canvas id="canvas7" width="500" height="500"></canvas>
		<script>
			oCanvas = document.getElementById('canvas7')
			ctx = oCanvas.getContext('2d'); //拿到画笔
			ctx.beginPath();

			// 绘制一个矩形线框
			ctx.rect(
				50, 50, // 矩形左上角，x y 坐标
				300, 300 // 矩形宽高
			)

			// 路径闭合: 表示路径已经绘制完毕，这里是矩形，可不要这个
			ctx.closePath();

			// 绘制路径
			ctx.stroke();
		</script>
	</div>

	<div>
		<a id="绘制曲线"></a>
		<h1>绘制折线</h1>
		<canvas id="canvas2" width="500" height="500"></canvas>
		<script>
			oCanvas = document.getElementById('canvas2')
			ctx = oCanvas.getContext('2d'); //拿到画笔
			// ctx.beginPath();

			ctx.moveTo(100, 250);
			ctx.lineTo(400, 250);
			ctx.lineTo(300, 150);
			ctx.lineTo(450, 100);

			// 路径闭合: 表示路径已经绘制完毕
			ctx.closePath();

			// 绘制路径
			ctx.stroke();
		</script>
	</div>
	<div>
		<a id="绘制圆弧"></a>
		<h1>绘制圆弧</h1>
		<canvas id="canvas3" width="500" height="500"></canvas>
		<script>
			/** @type {HTMLCanvasElement} */ // 提示补全
			oCanvas = document.getElementById('canvas3')

			ctx = oCanvas.getContext('2d'); //拿到画笔

			ctx.fillStyle = 'teal'
			ctx.fillRect(0, 0, 200, 200)

			// 开始新的一条路径
			ctx.beginPath();

			// 绘制圆弧
			ctx.arc(
				200, 200, // 圆心xy坐标
				100, // 半径
				0.5 * Math.PI, // 圆弧开始的弧度
				2 * Math.PI, // 圆弧结束的弧度
				false // 是否按照逆时针画圆
			)

			// 路径闭合: 表示路径已经绘制完毕
			// ctx.closePath();

			// 绘制路径
			ctx.stroke();

		</script>
	</div>

	<div>
		<a id="绘制圆角矩形"></a>
		<h1>绘制圆角矩形</h1>
		<canvas id="canvas4" width="500" height="500"></canvas>
		<script>

			window.drawPoint = (x, y, color = 'red') => {
				let w = 10;
				let h = 10;
				ctx.save()
				ctx.globalAlpha = 0.5
				ctx.fillStyle = color
				ctx.fillRect(
					x - w / 2, y - w / 2,
					w, h
				)
				ctx.restore()
			}


			oCanvas = document.getElementById('canvas4')

			ctx = oCanvas.getContext('2d'); //拿到画笔

			ctx.fillStyle = 'blue'
			ctx.fillRect(0, 0, 50, 50)
			// ctx.strokeRect(0, 0, 350, 25)

			// 开始一个新的路径
			ctx.beginPath();

			let w = 300
			let h = 300
			let radius = 50
			let x = 50
			let y = 50
			// 从左上角开始
			ctx.moveTo(x + radius, y)
			// 刚开始的点位
			drawPoint(x + radius, y)

			// 右上角
			ctx.arcTo(
				x + w, y, // 两切线交点的横坐标 纵坐标
				x + w, y + radius, // 第二条切线上一点的横坐标 纵坐标
				radius, // 圆弧 半径
			)
			// 虚拟点位
			drawPoint(x + w, y, 'red')
			// 目标点位
			drawPoint(x + w, y + radius, 'green')

			// 右下角
			ctx.arcTo(
				x + w, y + h,
				x, y + h,
				radius
			)
			// 虚拟点位
			drawPoint(x + w, y + h, 'red')
			// 目标点位
			drawPoint(x, y + h, 'green')


			// 左下角
			ctx.arcTo(
				x, y + h,
				x, y,
				radius
			)

			// 虚拟点位
			drawPoint(x, y + h, 'red')
			// 目标点位
			drawPoint(x, y, 'green')

			// 左上交
			ctx.arcTo(
				x, y,
				x + radius, y,
				radius
			)

			// 虚拟点位
			drawPoint(x, y, 'red')
			// 目标点位
			drawPoint(x + radius, y, 'green')

			// 绘制路径
			ctx.stroke();

			// 路径闭合: 表示路径已经绘制完毕
			ctx.closePath();
		</script>
	</div>


	<div>
		<h1>绘制贝塞尔曲线</h1>
		<canvas id="canvas5" width="500" height="500"></canvas>
		<script>

			oCanvas = document.getElementById('canvas5')
			ctx = oCanvas.getContext('2d'); //拿到画笔

			const dottedLine = (x1, y1, x2, y2, color = 'red') => {
				ctx.save();

				// 开始新的一条路径
				ctx.beginPath();

				ctx.moveTo(x1, y1);
				ctx.lineTo(x2, y2);
				ctx.globalAlpha = .4;

				// 绘制路径
				ctx.stroke();

				// 路径闭合: 表示路径已经绘制完毕
				ctx.closePath();
				ctx.restore();
			}

			// ctx.beginPath();

			let endx = 450;
			let endy = 50;

			let p1x = 200;
			let p1y = 250;

			let p2x = 150;
			let p2y = 150
			let startX = 50
			let startY = 50

			ctx.moveTo(startX, startY);

			// 绘制 贝塞尔曲线
			ctx.bezierCurveTo(
				p1x, p1y, // 第一个控制的的 x y 坐标
				p2x, p2y, // 第二个控制的的 x y 坐标
				endx, endy // 目标点 x y 坐标
			)

			// 绘制路径
			ctx.stroke();

			// 路径闭合: 表示路径已经绘制完毕
			// ctx.closePath();

			// 虚拟点位 1
			drawPoint(p1x, p1y, 'red');
			// 虚线
			dottedLine(startX, startY, p1x, p1y);

			// 虚拟点位 2
			drawPoint(p2x, p2y, 'blue');
			// 虚线
			dottedLine(p2x, p2y, endx, endy);

		</script>
	</div>

	<div>
		<a id="绘制二次曲线"></a>
		<h1>绘制二次曲线</h1>
		<canvas id="canvas6" width="500" height="500"></canvas>
		<script>
			oCanvas = document.getElementById('canvas6')
			ctx = oCanvas.getContext('2d'); //拿到画笔
			ctx.beginPath();

			(() => {
				let startX = 50
				let startY = 50

				let endX = 450
				let endY = 50

				let ctrlX = 60
				let ctrlY = 150

				ctx.moveTo(50, 50)

				// 从上一个点开始, 绘制一条二次曲线
				ctx.quadraticCurveTo(
					ctrlX, ctrlY, // 第一个控制点 x y
					endx, endY // 目标坐标 x y
				)

				// 绘制路径
				ctx.stroke();

				// 路径闭合: 表示路径已经绘制完毕
				ctx.closePath();

				// 虚拟点位 1
				drawPoint(ctrlX, ctrlY, 'red');
				// // 虚线
				dottedLine(startX, startY, ctrlX, ctrlY);
			})();

		</script>
	</div>


	</div>

</body>

</html>